Skip to content

Conversation

@LostinTimeandspaceYT
Copy link
Contributor

The LTC®2959 is an ultra-low power battery gas gauge
that accurately measures charge, voltage, current and
temperature. Its wide input voltage range and its low
operating current make the LTC2959 suitable for many
applications, including duty-cycled systems that operate
over long lifetime.

This driver integrates with Zephyr’s fuel gauge subsystem to provide access to telemetry data such as voltage, current, temperature, and accumulated charge.

Tested on custom hardware with known RSENSE configuration and verified against datasheet behavior.

Signed-off-by: Nathan Winslow [email protected]

@github-actions
Copy link

Hello @LostinTimeandspaceYT, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

@fmoessbauer
Copy link
Contributor

IMHO this should go after #90310 (or at least 12a8422) so things can be tested with the generic example.

@kartben kartben requested a review from Copilot May 23, 2025 07:06

This comment was marked as off-topic.

@sonarqubecloud
Copy link

@ttmut
Copy link
Contributor

ttmut commented Jul 21, 2025

Hi @LostinTimeandspaceYT,

Thanks for your contribution. Please refactor your commit title and body so that they adhere to Pull Request Guidelines.

See these examples:

You should also merge your commits into a single commit to retain bisectability as described in PR Requirements

Do not forget to address the compliance failures as well: https://github.com/zephyrproject-rtos/zephyr/actions/runs/15276958086/job/42967094398?pr=90356

@LostinTimeandspaceYT LostinTimeandspaceYT changed the title drivers: fuel_guage: Add support for Analog Devices LTC2959 drivers: fuelguage: Add ADI LTC2959 driver Jul 21, 2025
@zephyrbot zephyrbot requested a review from DBS06 July 21, 2025 13:36
@LostinTimeandspaceYT
Copy link
Contributor Author

Thank you @ttmut for reviewing this PR. I will have time later this week to work on the needed changes and consolidate the commits as per the guidelines.

Copy link
Contributor

@DBS06 DBS06 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, thanks for your contribution and overall it looks well done!
I also looked inside the datasheet and as far as I see you implemented every necessary/interesting feature from the IC. Interestingly, the IC does not provide a relative state of charge in percent, but it is what it is.

Please also add an e.g. ltc2959-emulation, for example emul_lc709203f.c, emul_max17048, or emul_bq27z746.c and also a test (look here), because this helps a lot to avoid possible future breaking changes and further increase the test coverage and quality of Zephyr.

/* Used when ACR is controlled via firmware */
#define LTC2959_ACR_CLR (0xFFFFFFFF)

#ifdef CONFIG_FUEL_GAUGE_LTC2959_RSENSE_MOHMS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be done via Devicetree as stated here can be removed here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, these are helpful examples. I will add an emul and ztest.

/* LTC2959 Register Map — from datasheet (Rev A) */

/* Status and Control */
#define LTC2959_REG_STATUS (0x00)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to put all registers in an enum, see here for example.
Furthermore, except the enum ltc2959_custom_props and the registers, everything else (the constant values even including the struct ltc2959_config , etc.) can/should be moved to the ltc2959.c, because there is no need to have it in the public interface.

Comment on lines 211 to 212
case LTC2959_GPIO_MODE_ALERT:
case LTC2959_GPIO_MODE_CHGCOMP:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case LTC2959_GPIO_MODE_ALERT:
case LTC2959_GPIO_MODE_CHGCOMP:

If they are doing nothing, the default: branch is enough.

Comment on lines 169 to 174
FUEL_GAUGE_VOLTAGE_HIGH_THRESHOLD,
FUEL_GAUGE_VOLTAGE_LOW_THRESHOLD,
FUEL_GAUGE_CURRENT_HIGH_THRESHOLD,
FUEL_GAUGE_CURRENT_LOW_THRESHOLD,
FUEL_GAUGE_TEMPERATURE_HIGH_THRESHOLD,
FUEL_GAUGE_TEMPERATURE_LOW_THRESHOLD,
Copy link
Contributor

@DBS06 DBS06 Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For FUEL_GAUGE_VOLTAGE_LOW_THRESHOLD the FUEL_GAUGE_LOW_VOLTAGE_ALARM property already exists.
But nevertheless, I think it is valid to add the other 5 properties to the fuel_gauge.h interface, for me it seems legit to add them, because if we already have a low-voltage-alarm why not have a high-voltage-alarm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I elected not to use FUEL_GAUGE_LOW_VOLTAGE_ALARM as that reports a percentage of charge. The purpose of these properties is for configuring bounds to trigger a fault in the status register. I am not sure how other ICs of this ilk operate, but I agree @DBS06, I think adding them would make sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LostinTimeandspaceYT FUEL_GAUGE_LOW_VOLTAGE_ALARM is described in fuel_gauge.h as /** Low Cell Voltage Alarm (uV)*/ so it does not "reports a percentage of charge", I think you mismatch that with FUEL_GAUGE_STATE_OF_CHARGE_ALARM which is described as /** Remaining state of charge alarm (percent, 0-100) */.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DBS06 You're right I did, classic off-by-1 😅
image

I could change the current FUEL_GAUGE_LOW_XXXX_THRESHOLD to FUEL_GAUGE_LOW_XXX_ALARM to have the property names be consistent with the current API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could change the current FUEL_GAUGE_LOW_XXXX_THRESHOLD to FUEL_GAUGE_LOW_XXX_ALARM to have the property names be consistent with the current API.

Exactly what I meant! You can keep the register names as it is and just adopt the property names (they are more or less generic names).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started work on this driver in a project on v4.1.0 and it looks like the FUEL_GAUGE_LOW_VOLTAGE_ALARM property was added after that release. I noticed the discrepancy when attempting to build in that project. I Apologize for the confusion.

Copy link
Contributor

@DBS06 DBS06 Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to apologize! That's why code reviews are for.

Yes, I added it after my last PR #90310, which went bigger than originally expected 🤔

Just a minor hint, if you are adding additional properties do that in a separate commit (look at the commits from here #90310) and it should be the first one, as far as I see you can squash all other currently existing commits into one commit. If you add a test for your driver do that in another commit. So basically in the end you have three commits which will be pushed in the main branch.

I hope this helps!

@github-actions
Copy link

github-actions bot commented Jul 28, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff

All manifest checks OK

Note: This message is automatically posted and updated by the Manifest GitHub Action.

aaronemassey
aaronemassey previously approved these changes Oct 3, 2025
Copy link
Member

@aaronemassey aaronemassey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding tests/ emulator!

@zephyrbot zephyrbot added area: Tests Issues related to a particular existing or missing test area: Boards/SoCs area: Devicetree Bindings labels Oct 11, 2025
@zephyrbot zephyrbot requested a review from nashif October 11, 2025 12:38
@DBS06
Copy link
Contributor

DBS06 commented Oct 11, 2025

You need to rebase your branch onto master and resolve the merge conflicts

Adds properties to fuel gauge api to support ADI LTC2959.

Signed-off-by: Nathan Winslow <[email protected]>
DBS06
DBS06 previously approved these changes Oct 11, 2025
Adds test and native sim support for ADI LTC2959 fuel gauge.

Signed-off-by: Nathan Winslow <[email protected]>
@LostinTimeandspaceYT
Copy link
Contributor Author

LostinTimeandspaceYT commented Oct 12, 2025

CI issue was due to set_adc_mode. I had originally intended on exposing gpio configuration as a separate prop, but elected against it. I have widened the mask to to accept all the valid bits in the control register.
Screenshot from 2025-10-12 08-42-19

@zephyrbot zephyrbot requested a review from DBS06 October 12, 2025 12:50
@sonarqubecloud
Copy link

@DBS06
Copy link
Contributor

DBS06 commented Oct 22, 2025

@ttmut can you review this PR again and look if your requested changes are done to your satisfaction?

@ttmut
Copy link
Contributor

ttmut commented Oct 22, 2025

@ttmut can you review this PR again and look if your requested changes are done to your satisfaction?

Apologies, missed the notification somehow.

@DBS06
Copy link
Contributor

DBS06 commented Oct 22, 2025

@LostinTimeandspaceYT so far everything is complete and the PR is ready for merge! thanks a lot for your contribution!
We/you just need someone with merge rights, e.g. @kartben or @MaureenHelm

@jhedberg jhedberg merged commit 72fac96 into zephyrproject-rtos:main Oct 22, 2025
26 checks passed
@github-actions
Copy link

Hi @LostinTimeandspaceYT!
Congratulations on getting your very first Zephyr pull request merged 🎉🥳. This is a fantastic achievement, and we're thrilled to have you as part of our community!

To celebrate this milestone and showcase your contribution, we'd love to award you the Zephyr Technical Contributor badge. If you're interested, please claim your badge by filling out this form: Claim Your Zephyr Badge.

Thank you for your valuable input, and we look forward to seeing more of your contributions in the future! 🪁

@jhedberg
Copy link
Member

Looks like this broke the CI build on main: https://github.com/zephyrproject-rtos/zephyr/actions/runs/18721827138/job/53395989790

[70/112] Building C object zephyr/drivers/fuel_gauge/CMakeFiles/drivers__fuel_gauge.dir/ltc2959/ltc2959.c.obj
FAILED: zephyr/drivers/fuel_gauge/CMakeFiles/drivers__fuel_gauge.dir/ltc2959/ltc2959.c.obj 
ccache /usr/lib/llvm-20/bin/clang -DKERNEL -DK_HEAP_MEM_POOL_SIZE=0 -DTC_RUNID=ea35e6f8948448a2fe78cc37a35df94e -DZVFS_OPEN_SIZE=8 -D__ZEPHYR_SUPERVISOR__ -D__ZEPHYR__=1 -I/__w/zephyr/zephyr/twister-out/native_sim_native/llvm/tests/drivers/fuel_gauge/ltc2959/drivers.fuel_gauge.ltc2959/zephyr/include/generated/zephyr -I/__w/zephyr/zephyr/include -I/__w/zephyr/zephyr/twister-out/native_sim_native/llvm/tests/drivers/fuel_gauge/ltc2959/drivers.fuel_gauge.ltc2959/zephyr/include/generated -I/__w/zephyr/zephyr/soc/native/inf_clock -I/__w/zephyr/zephyr/boards/native/native_sim -I/__w/zephyr/zephyr/lib/midi2/. -I/__w/zephyr/zephyr/scripts/native_simulator/common/src/include -I/__w/zephyr/zephyr/scripts/native_simulator/native/src/include -I/__w/zephyr/zephyr/subsys/testsuite/include -I/__w/zephyr/zephyr/subsys/testsuite/coverage -I/__w/zephyr/zephyr/subsys/testsuite/ztest/include -I/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/. -I/__w/zephyr/modules/hal/microchip/include -I/__w/zephyr/modules/hal/ti/mspm0/source/ti/devices/msp/. -I/__w/zephyr/modules/hal/ti/mspm0/source/ti/devices/msp/m0p -I/__w/zephyr/modules/hal/ti/mspm0/source/ti/devices/msp/peripherals -I/__w/zephyr/modules/hal/ti/mspm0/source/ti/devices/msp/peripherals/m0p -I/__w/zephyr/modules/hal/ti/mspm0/source/ti/devices/msp/peripherals/m0p/sysctl -Wshadow -fno-strict-aliasing -Werror -Oz -imacros /__w/zephyr/zephyr/twister-out/native_sim_native/llvm/tests/drivers/fuel_gauge/ltc2959/drivers.fuel_gauge.ltc2959/zephyr/include/generated/zephyr/autoconf.h -fno-common -g -gdwarf-4 -fcolor-diagnostics --config=/__w/zephyr/zephyr/cmake/toolchain/llvm/clang_libgcc.cfg -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-unused-but-set-variable -Wno-typedef-redefinition -Wno-deprecated-non-prototype -Wdouble-promotion -Wno-pointer-sign -Wpointer-arith -Wno-self-assign -Wno-initializer-overrides -Wno-section -Wno-gnu -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -Wno-vla -fmacro-prefix-map=/__w/zephyr/zephyr/tests/drivers/fuel_gauge/ltc2959=CMAKE_SOURCE_DIR -fmacro-prefix-map=/__w/zephyr/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/__w/zephyr=WEST_TOPDIR -ffunction-sections -fdata-sections -m32 -msse2 -mfpmath=sse -fvisibility=hidden -std=c11 -MD -MT zephyr/drivers/fuel_gauge/CMakeFiles/drivers__fuel_gauge.dir/ltc2959/ltc2959.c.obj -MF zephyr/drivers/fuel_gauge/CMakeFiles/drivers__fuel_gauge.dir/ltc2959/ltc2959.c.obj.d -o zephyr/drivers/fuel_gauge/CMakeFiles/drivers__fuel_gauge.dir/ltc2959/ltc2959.c.obj -c /__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:465:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  465 |                 uint8_t raw_st;
      |                 ^
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:478:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  478 |                 uint16_t raw_voltage;
      |                 ^
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:495:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  495 |                 uint16_t raw_current;
      |                 ^
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:511:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  511 |                 uint16_t raw_temp;
      |                 ^
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:530:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  530 |                 uint32_t acr;
      |                 ^
/__w/zephyr/zephyr/drivers/fuel_gauge/ltc2959/ltc2959.c:640:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
  640 |                 uint32_t counts = ltc2959_uah_to_counts(val.remaining_capacity, cfg);
      |                 ^
6 errors generated.

The solution is likely to add braces around those case statements, i.e.:

	case FOO: {
		...

		break;
	}
	case BAR: {
		...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Boards/SoCs area: Devicetree Bindings area: Fuel Gauge area: Tests Issues related to a particular existing or missing test platform: ADI Analog Devices, Inc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.